/*
 * author : Dinh Ngoc Tuan Vu (A0092633)
 */
package sg.edu.nus.iss.team4ft.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import sg.edu.nus.iss.team4ft.exception.InvalidOperationException;
import sg.edu.nus.iss.team4ft.util.DateUtil;

public class Account implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String accountNumber;
	private ArrayList<Plan> plans = new ArrayList<Plan>();
	
	public Account(){
		accountNumber = "ACC" + DateUtil.format(DateUtil.getDate(), "yyMMddHHmmss");
	}	
	
	public void setAccountNumber(String accountNumber) {
		this.accountNumber = accountNumber;
	}

	public String getAccountNumber() {
		return this.accountNumber;
	}

	public Boolean accountNumberEquals(String accNum) {
		return this.accountNumber.equals(accNum);
	}
	
	public String toString(){
		return this.accountNumber.toString();
	}
	
	public boolean equals(Account account){
		if(this.accountNumber.equals(account.accountNumber)){
			return true;
		}else if(this.toString().equals(account.toString())){
			return true;
		}else{
			return false;
		}
	}
	
	//A new plan can be added only if
	//	1. No such plan exist (or)
	//	2. A plan of same type exist but it is unsubscripe
	public void subscripeNewPlan(Plan plan) throws InvalidOperationException{
		ArrayList<Plan> removePlans = new ArrayList<Plan>();
		for (Plan p : plans) {
			if(p.getServiceId() == plan.getServiceId())
				removePlans.add(p);
//			if(!p.canInclude(plan))
//				throw new InvalidOperationException("Trying to add duplicate plan. Already a plan of same type is exist in active state.");
		}
		plans.removeAll(removePlans);
		
		for (Plan plan2 : plans) {
			if(plan2.getPlanCode() == plan.getPlanCode() && plan2.getEndDate() != null && DateUtil.dateIsBefore(plan.getStartDate(), plan2.getEndDate()))
				throw new InvalidOperationException("Plan of Same type was deactivated on " +DateUtil.defaultFormat(plan2.getEndDate()) 
						+ ". Subscribe the current plan on or after "+ DateUtil.defaultFormat(plan2.getEndDate()));
		}
		
		plans.add(plan);
	}
	
	public Plan getPlan(PlanCode planCode) throws CloneNotSupportedException {
		Plan plan = null;
		 for (Plan p : plans) {
			if(p.getPlanCode() == planCode)
				plan = p.clone();
		}
		return plan;
	}
	
	public ArrayList<Plan> getPlans() {
		return new ArrayList<Plan>(plans);
	}
	

	
	@Override
	protected Account clone() throws CloneNotSupportedException {
		Account a = new Account();
		a.setAccountNumber(this.accountNumber);
		a.plans = this.getPlans();
		return a;
	}
	
	public ArrayList<String> getTelephoneNumbers(){
		ArrayList<String> numbers = new ArrayList<String>();
		for (Plan p : plans) {
			if(p instanceof VoicePlan)
				numbers.add(((VoicePlan)p).getTelephoneNumber().toString());
		}
		return numbers;
	}

	public void deregister() throws InvalidOperationException {
		List<Plan> removePlans = new ArrayList<Plan>();
		
		for (Plan p : this.plans) {
			p.setFeatureStartDateOnDeactivation();
			if(!DateUtil.dateIsBefore(p.getStartDate(), DateUtil.getDate())){
				removePlans.add(p);
			}
		}		
		plans.removeAll(removePlans);
		
		for (Plan p : this.plans) {
			p.unsubscribeService(DateUtil.getDate());
		}		
	}
}
